/**
	@file hello.S
	@author Andrew D. Zonenberg
	@brief Simple "hello world" program
 */
 
.set noreorder					/*	Prevent any optimizations from reordering instructions!
									We want exe to exactly match source! */

.section .startup.bootvec, "ax", @progbits 
.globl _start
_start:
	jal			uartInit			/*	Initialize the UART before doing anything else */

	li			$t0, 0xa0000000		/*	t0 = start of RAM */
	lw			$t1, 0($t0)			/*	Load first word of RAM into $t1 */
	addiu		$t1, $t1, 1			/*	Add 1 to result. Tests forwarding from stall-for-mem */

	la			$t0, LEDBANKA		/*	t0 = &LEDBANKA
										Tests la pseudoop (lui + addiu) as well as symbol linking */
	
	li			$t1, 0x50			/*	t1 = 0x50
										Tests addiu instruction	 */
	addiu		$t1, $t1, 0x5		/*	t1 = 0x55 
										Tests forwarding from mem stage	*/
	
	li			$t2, 1				/*	t2 = 1 */
	
	addu		$t3, $t1, $t2		/*	t3 = 0x56
										Tests addu instruction, plus forwarding from both mem and writeback stage. */
	add			$t3, $t3, $t2		/*	t3 = 0x57
										Tests add instruction without overflow */
	li			$t4, 0xfe			/*	t4 = 0xfe */
	and			$t5, $t3, $t4		/*	t5 = 0x56
										Tests and instruction */
	andi		$t6, $t3, 0xfe		/*	t6 = 0x56 
										Tests andi instruction, plus forwarding from post-writeback in register file */
	addi		$t2, $t6, 1			/*	t2 = 0x57
										Tests addi instruction without overflow */
									
	li			$t3, 1				/*	t3 = 1 */
	sub			$t2, $t2, $t3		/*	t2 = 0x56
										Tests sub instruction without underflow */
	subu		$t2, $t2, $t3		/*	t2 = 0x55
										Tests subu instruction */
	li			$t3, 0xf000			/*	t3 = 0xf000 */
	or			$t4, $t2, $t3		/*	t4 = 0xf055 
										Tests or instruction */
	ori			$t4, $t4, 0x0f00	/*	t4 = 0xff55
										Tests ori instruction */
										
	sw			$t4, 0($t0)			/*	store 0xff55 to *t0 (LEDBANKA)
										tests sw instruction */
										
	la			$t4, .skipit		/*	Need to get an absolute address to jr to */
	jr			$t4					/*	Test jr instruction */
	
.noskip:
	li			$t0, 0xdead			/*	will be executed if jr fails */
	
.skipit:
	li			$t0, 0xbeef			/*	will be executed regardless of jr result */
	
	xori		$t0, 0xffff			/*	invert low order bits
										tests xori instruction*/
	li			$t1, 0xffff
	xor			$t0, $t0, $t1		/*	invert low order bits again
										tests xor instruction */
										
	la			$t0, U1TXBUF		/*	Prepare to print to the UART */
	li			$t1, 0x41			/*	Print 'A' */
	sw			$t1, 0($t0)	
				
.infloop:							/*	Infinite loop
										tests j instruction */
	j			.infloop

.section .startup, "ax", @progbits	/*	Function in another section but within range of a short jump */
.globl uartInit
uartInit:							/*	Nothing earth-shattering as far as instructions go, just set up the UART */
	la			$t0, U1BRG
	li			$t1, 868			/*	100 MHz / 115200 bps */
	sw			$t1, 0($t0)
	jr			$ra
									
	/* TODO: Test addi, add, sub with over/underflow */

	/* TODO: implement syscall, break, srav, coprocessor instructions */
	
	/* In MIPS-1 but not implemented: lwl, lwr, swl, swr */
